#include "ClientFrame.hpp"

IMPLEMENT_APP(HangmanApp)

bool HangmanApp::OnInit()
 {
     ClientFrame *frame = new ClientFrame( wxT("wxHangman by Yoann Buch."), 
          wxPoint(50,50), wxSize(600,700));

	 //Get Server IP before showing anything
	 wxTextEntryDialog dialog(frame, wxT("Server IP"), wxT("Server IP"),wxT("127.0.0.1"));
     do 
	 {
	 }while(dialog.ShowModal()!= wxID_OK);

	 frame->setIPServer(dialog.GetValue());

     frame->Show(TRUE);
     SetTopWindow(frame);

	 //Connect to server
	 frame->ConnectToServer();
	 

     return TRUE;
 } 

 ClientFrame::ClientFrame(const wxString& title, 
        const wxPoint& pos, const wxSize& size)
 : wxFrame((wxFrame *)NULL, -1, title, pos, size)
 {
    //Initialize components  

	 _IPServer = new wxString(wxEmptyString);
	 _guess = new wxString(wxEmptyString);
	 nbFailure=0;
	 victory=0;
	 _socket=NULL;
	 _wordToShow=new wxString();

	_tbLetter = new wxTextCtrl(this, wxID_ANY);
	_btGuess = new wxButton(this,ID_btGuess,wxT("OK"));
	_lblWord = new wxStaticText(this, wxID_ANY,wxEmptyString);
	_lblNbFailure = new wxStaticText(this, wxID_ANY,wxEmptyString);

	//Menu
	_menu = new wxMenu();
	_menu->Append(ID_menuNew,wxT("New"));
	_menu->Append(ID_menuNewIP,wxT("Change server IP"));
	_menu->AppendSeparator();
	_menu->Append(ID_menuQuit,wxT("Quit"));
	wxMenuBar* menuBar = new wxMenuBar();	
	this->SetMenuBar(menuBar);
	menuBar->Append(_menu, wxT("File"));

	//Window to render hangman
	window = new HangManWindow(this);
	window->SetSize(wxSize(500,500));
	window->SetPosition(wxPoint(0,50));

	//Layout
	sizerMain = new wxBoxSizer(wxHORIZONTAL);
	sizerMain->Add(_tbLetter);
	sizerMain->Add(_btGuess);
	sizerMain->Add(_lblWord);
	sizerMain->Add(_lblNbFailure);
	SetSizer(sizerMain);

	//Status bar
	CreateStatusBar(3);

	window->Refresh();

 }

 void ClientFrame::OnClick_btGuess(wxCommandEvent& event)
 {
	 SendGuessToServer(wxString(_tbLetter->GetValue()));
	 //clear tb
	 _tbLetter->Clear();
	
	 window->Refresh();
 }

 void ClientFrame::OnClick_menuQuit(wxCommandEvent& event)
 {
	 //Quit program
	 Close();
 }

 void ClientFrame::OnClick_menuNew(wxCommandEvent& event)
 {
	 ConnectToServer(); 
	 nbFailure=0;
	 victory=0;
	 _btGuess->Enable();
 }

 void ClientFrame::OnClick_menuNewIP(wxCommandEvent& event)
 {
	 wxTextEntryDialog dialog(this,wxT("Server IP"), wxT("Server IP"),*_IPServer);

	 if (dialog.ShowModal()== wxID_OK)
	 {
		 setIPServer(dialog.GetValue());
	 }
 }

void ClientFrame::ConnectToServer()
{
    wxIPV4address addr;
    addr.Hostname(*_IPServer);
    addr.Service(3000);

	if(_socket!=NULL)
	{
		_socket->Destroy();
	}

    // Create the socket
    wxSocketClient *sockClient = new wxSocketClient();

    // Subscribe to most events
	sockClient->SetEventHandler(*this, SOCKET_ID);
    sockClient->SetNotify(wxSOCKET_CONNECTION_FLAG |
                                        wxSOCKET_INPUT_FLAG |
                                        wxSOCKET_LOST_FLAG);
    sockClient->Notify(true);

    // Wait for the connection event
    sockClient->Connect(addr, false);

}

void ClientFrame::OnSocketEvent(wxSocketEvent& event)
{
	 // Common buffer shared by the events
    char buf[100];

	_socket = event.GetSocket();

    switch(event.GetSocketEvent())
    {
        case wxSOCKET_CONNECTION:
        {
            _socket->Read(buf, sizeof(buf));

			wxStringTokenizer tokenizer(wxString(buf, wxConvUTF8), wxT(":"));

			wxString sNbFailure = tokenizer.GetNextToken();
			nbFailure = wxAtoi(sNbFailure);
			wxString wordToShow = tokenizer.GetNextToken();
			_wordToShow->clear();
			_wordToShow->append(wordToShow);
			//_lblWord->SetLabel(wordToShow);
			wxString victory = tokenizer.GetNextToken();

			window->Refresh();

            break;
        } 
        case wxSOCKET_INPUT:
        {
			_socket->Read(buf, sizeof(buf));
            
			wxStringTokenizer tokenizer(wxString(buf, wxConvUTF8), wxT(":"));

			wxString sNbFailure = tokenizer.GetNextToken();
			int oldFailure = nbFailure;
			nbFailure = wxAtoi(sNbFailure);

			if(oldFailure==nbFailure)
			{
				//good guess
				_lblWord->SetLabel(wxT("Good guess"));
			}
			else
			{
				//wrong guess
				_lblWord->SetLabel(wxT("Wrong guess"));
			}

			//_lblNbFailure->SetLabel(sNbFailure);
			wxString wordToShow = tokenizer.GetNextToken();
			_wordToShow->clear();
			_wordToShow->append(wordToShow);
			//_lblWord->SetLabel(wordToShow);
			wxString sVictory = tokenizer.GetNextToken();

			victory = wxAtoi(sVictory);

			if(victory==1)
			{
				//win			
				_socket->Destroy();
				_socket=NULL;
				_btGuess->Disable();
			}
			else if(victory==2)
			{
				//loose
				_socket->Destroy();
				_socket=NULL;
				_btGuess->Disable();
			}
            
			window->Refresh();

            break;
        }

        // The server hangs up after sending the data
        case wxSOCKET_LOST:
        {
            _socket->Destroy();
			_socket=NULL;
			window->Refresh();
            break;
        }
    }
	if (_socket==NULL)
	{
		SetStatusText(wxT("Disconnected from server"), 0);
	}
	else if ( _socket->IsConnected())
		SetStatusText(wxT("Connected to server"), 0);
	else
		SetStatusText(wxT("Disconnected from server"), 0);
}

void ClientFrame::setGuess(wxString& guess)
{
	_guess->clear();
	_guess->Append(guess);
}

void ClientFrame::setIPServer(wxString& IP)
{
	_IPServer->clear();
	_IPServer->append(IP);
}

void ClientFrame::SendGuessToServer(wxString& guess)
{
	setGuess(guess);

	char buf[10];
    strcpy(buf, (const char*)guess.mb_str(wxConvUTF8));

	_socket->Write(buf,sizeof(buf));
}

int ClientFrame::getNbFailure()
{
	return nbFailure;
}


 HangManWindow::HangManWindow(wxWindow* parent)
    : wxWindow(parent, -1)
 {
 }

void HangManWindow::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
	dc.SetDeviceOrigin(10,50);
    dc.SetBrush(*wxTRANSPARENT_BRUSH);

	wxPen pen(*wxRED,5);
	dc.SetPen(pen);

	ClientFrame *CF = (ClientFrame*) GetParent();
	int nbFailure = CF->getNbFailure();
	int victory=CF->victory;

	wxFont(20,wxFONTFAMILY_MODERN, wxNORMAL, wxBOLD);
	if(victory==1)
	{
		//win
		dc.DrawText(wxT("You won"),250,25);
	}
	else if(victory==2)
	{
		dc.DrawText(wxT("You lost"),250,25);
		
	}

	dc.DrawText(*(CF->_wordToShow),250,0);

	if(nbFailure > 0)
	{
		 int a= 1;
	}
	switch(nbFailure)
	{
	case 10:
		 dc.DrawLine(180,230,150,260);
	case 9:
		 dc.DrawLine(180,230,210,260);
	case 8:
		 //Arms
		 dc.DrawLine(140,140,220,140);
	case 7:
		 dc.DrawLine(180,110,180,230);
	case 6:
		 //head	
		 dc.DrawEllipse(155,60,50,50);
	case 5:
		 dc.DrawLine(180,30,180,60);
	case 4:
		 dc.DrawLine(70,70,100,30);
	case 3:
		 dc.DrawLine(50,30,230,30);
	case 2:
		 dc.DrawLine(70,370,70,30);
	case 1:
		dc.DrawLine(50,370,250,370);
		break;
	}	
	dc.SetPen(wxNullPen);

 }


